package org.geekbang.thinking.in.spring.ioc.bean.lifecycle;

import com.think.in.spring.ioc.overview.domain.SuperUser;
import com.think.in.spring.ioc.overview.domain.User;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.util.ObjectUtils;

/**
 * @author : zjj
 * @date : 2022/2/25 17:18
 */
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {


    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {

        if(ObjectUtils.nullSafeEquals("superUser",beanName) && SuperUser.class.equals(beanClass) ){
            return new SuperUser();
        }
        return null;
    }


    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if(ObjectUtils.nullSafeEquals("userHolder",beanName)&& UserHolder.class.equals(bean.getClass())){
            UserHolder userHolder = (UserHolder) bean;
            userHolder.setDescription("test v3");
            return userHolder;
        }
        return bean;
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if(ObjectUtils.nullSafeEquals("user",beanName) ){
            User user = (User)bean;
            user.setId(1);
            user.setName("test");
            return false;
        }
        return true;
    }

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {

        if(ObjectUtils.nullSafeEquals("userHolder",beanName) && UserHolder.class.equals(bean.getClass())){
            final MutablePropertyValues propertyValues;

            if(pvs instanceof MutablePropertyValues){
                propertyValues = (MutablePropertyValues) pvs;

            }else {
                propertyValues = new MutablePropertyValues();
            }

            propertyValues.addPropertyValue("number","1");

            if(propertyValues.contains("description")){
                propertyValues.removePropertyValue("description");
                propertyValues.add("description","test v2");
            }

            return propertyValues;
        }

        return null;
    }
}
